﻿using System;
using System.Collections.Generic;
using System.Web;
using System.IO;
using System.Threading;

namespace HttpUploader5.demoAccess.db
{
	/// <summary>
	/// 文件续传类
	/// </summary>
	public class FileResumer
	{
		public long m_FileSize;		//文件总大小。
		string m_FileMD5;	//
		long m_RangePos;		//文件块起始位置
		public long RangePos
		{
			set { this.m_RangePos = value; }
		}
		int m_RangeSize;	//文件块大小

		//文件读写锁，防止多个用户同时上传相同文件时，出现创建文件的错误
		static ReaderWriterLock m_writeLock = new ReaderWriterLock();

		public FileResumer()
		{
		}

		/// <summary>
		/// 根据文件大小创建文件。
		/// 注意：多个用户同时上传相同文件时，可能会同时创建相同文件。
		/// </summary>
		public void CreateFile(string filePath)
		{
			//文件不存在则创建
			if (!File.Exists(filePath))
			{
				//创建文件
				//这里存在多个线程同时创建文件的问题。
				FileStream fs = File.OpenWrite(filePath);
				BinaryWriter w = new BinaryWriter(fs);
				for (long i = 0; i < this.m_FileSize; ++i)
				{
					w.Write((byte)0);
				}
				w.Close();
				fs.Close();
			}
		}

		/// <summary>
		/// 续传文件
		/// </summary>
		/// <param name="fileRange">文件块</param>
		/// <param name="fileRemote">远程文件完整路径。d:\www\web\upload\201204\10\md5.exe</param>
		public void Resumer(ref HttpPostedFile fileRange,string fileRemote)
		{
			//存在多个用户同时创建相同文件的问题。
			m_writeLock.AcquireWriterLock(1000);
			this.CreateFile(fileRemote);
			m_writeLock.ReleaseWriterLock();

			//上传的文件大小不为空
			if (fileRange.InputStream.Length > 0)
			{
				//文件已存在，写入数据
				//可能会有多个线程同时写文件。
				FileStream fs = new FileStream(fileRemote, FileMode.Open, FileAccess.Write, FileShare.Write);
				fs.Seek(this.m_RangePos, SeekOrigin.Begin);
				byte[] ByteArray = new byte[fileRange.InputStream.Length];
				fileRange.InputStream.Read(ByteArray, 0, (int)fileRange.InputStream.Length);
				fs.Write(ByteArray, 0, (int)fileRange.InputStream.Length);
				fs.Flush();
				fs.Close();
			}

		}
	}
}
